<?php

namespace App\Models\Traits;

use Carbon\Carbon;
use App\Models\SeckillProduct;
use App\Models\User;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Rainsens\Dinglog\Facades\Dinglog;

trait SeckillProductCacheTrait
{

	public static function seckillProductCacheKey()
	{
		return "seckill_product";
	}

	public static function seckillProductUnallowedAreaCacheKey($province)
	{
		return "seckill_product_unallowed_area_{$province}";
	}

	public static function seckillProductAliveCacheKey($sid)
	{
		return "seckill_product_alive_{$sid}";
	}

	public static function seckillProductQueueCacheKey($sid): string
	{
		return "seckill_product_queue_{$sid}";
	}

	public static function sIsInSoldCache($sid)
	{
		return Redis::exists(self::seckillProductQueueCacheKey($sid));
	}

	public static function sIsInCache($sid)
	{
		return Redis::exists(self::seckillProductAliveCacheKey($sid));
	}

	public static function sBuyFromCache($uid, $sid)
	{
		Redis::transaction(function () use ($uid, $sid) {
			Redis::rpop(self::seckillProductQueueCacheKey($sid));
			User::sAddSeckilOrderToUnpaidCache($uid, $sid);
		});
	}

	public static function addAddressToCache($uid, $cachedIds,$address)
	{
		User::sAddOrderAddressToUnpaidCache($uid, $cachedIds,$address);
	}


	public static function initCache()
	{

        Log::info("========== Start make seckill cache ......");
        SeckillProduct::makeAllCache();
		Log::info("========== seckill cache ready ......");
	}

	/**
	 * Cache all gold products in all gold rounds to redis.
	 */
	public static function makeAllCache()
	{
		self::available()->each(function (SeckillProduct $product) {

			$product->addToCache();
		});
	}

	public function addToCache()
	{
		
		if (!$this->is_open || $this->seckill_count == 0) return;

		

		for($i=1; $i<=$this->seckill_count; $i++ ){
			
			Redis::lpush(self::seckillProductQueueCacheKey($this->id), $i);
		}
		
		Redis::hMset(self::seckillProductAliveCacheKey($this->id),self::seckillProductTemp($this));

		$score = $this->is_new ? 1 : 2;
		Redis::zAdd(self::seckillProductCacheKey(), $score, $this->id );
		if($this->unallowed_area){
			$povinces = explode(",",$this->unallowed_area);
			foreach($povinces as $v){
				Redis::zAdd(self::seckillProductUnallowedAreaCacheKey($v), 1, $this->id);
			}

		}

		
		Log::debug("seckill: {$this->id} self added to cached");
	}

	public static function seckillProductTemp($data){
		$data = [
			'id'=>$data->id,
			'seckill_count' => $data->seckill_count,
			'seckill_count_all'  => $data->seckill_count_all,
			'is_new' => $data->is_new,
			'product_title' => $data->product->title ?? '',
			'description' => $data->product->description ?? '',
			'product_id'=> $data->product->id ?? 0,
			'product_sku_id' => $data->product->skus->first()->id ?? 0,
			'product_cover' => $data->product->cover_url ?? '',
			'sku_name' => $data->product->skus->first()->name ?? '',
			'sku_pic' => $data->product->skus->first()->pic ?? '',
			'sku_attr_value' => $data->product->skus->first()->attr_value ?? '',
			'sku_attr_value_index' => $data->product->skus->first()->attr_value_index ?? '',
			'price_cost' => $data->product->skus->first()->price_cost ?? '',
			'price' => $data->product->skus->first()->price ?? '',
			'price_vip' => $data->product->skus->first()->price_vip ?? '',
			'cover' => $data->product->cover ?? '',
			'comment_count' => $data->product->comment_count ?? '0',
			'comment_favor_rate' => $data->product->comment_favor_rate ?? '0',
			'cover_url'=> $data->product->cover_url ?? '0',
			'unallowed_area' => $data->unallowed_area ?? ''
		];

		return $data;

	}


	public static function getProducts($province,$new)
	{	
		$notAllowIds = [];
		if($province){
			
			$notAllowIds = Redis::zRange(self::seckillProductUnallowedAreaCacheKey($province),0,-1);

		}
		if($new){
			$ids = Redis::zRangeByScore(self::seckillProductCacheKey(),1,1);
		}else{

			$ids = Redis::zRangeByScore(self::seckillProductCacheKey(),2,2);
		}
		$products = [];
		foreach($ids as $id){
			$result = Redis::hGetAll(self::seckillProductAliveCacheKey($id));
			if($result && !in_array($id,$notAllowIds)){

				$products[] = $result;
			}

		}
		return $products;
	}
	
}
